212. k8s的親和性與反親和性

緣由

後端的服務,沒有HPA,所以目前都單Pod在執行。
但很不巧的,都在同一個Node裡面。
所以當一個Node出問題時,其他服務會一起陣亡。
但只有一個NodePool,也沒辦法用nodeSelector。

正文

GKE版本:1.27

先上範例,詳細說明在下面(格式有點跑掉,複製使用時要注意)。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: bms
  labels:
    group: svc
    app: backend
spec:
  replicas: 1
  selector:
    matchLabels:
      group: svc
      app: backend
  template:
    metadata:
      labels:
        group: svc
        app: backend
    spec:
      containers:
        - name: service
          image: my-image:v1.0.6
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
      affinity:
        podAntiAffinity:
			preferredDuringSchedulingIgnoredDuringExecution:
	        - weight: 100
		        podAffinityTerm:
	              labelSelector:
	                matchExpressions:
	                - key: app
	                  operator: In
	                  values:
	                  - gcp
	              topologyKey: kubernetes.io/hostname

這個的用途,主要是讓pod決定要跟哪個服務在一起,或不在一起。

其中比較重要的參數,

反親和性與親和性

前者是反親和性,不要跟哪個服務在一起
後者是親和性,要跟哪個服務在一起

必要與最好可以

前者是一定要達成下面的條件,
後者是最好是達成這樣的條件,並設成比重分數

選擇條件

requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
    matchExpressions:
    - key: app
      operator: In
      values:
      - gcp
  topologyKey: kubernetes.io/hostname  
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
  podAffinityTerm:
    labelSelector:
      matchExpressions:
      - key: app
        operator: In
        values:
        - gcp
    topologyKey: kubernetes.io/hostname

大致上的邏輯一樣,
但preferredDuringSchedulingIgnoredDuringExecution
必須加上podAffinityTerm

簡單說明規則,
選擇這個服務要跟哪個label當比較值。
然後,topologyKey 有點類似SQL group的概念,你要根據哪個來分群。

上面的例子是根據 node name來區分,
還有根據區域 kind.zone 來分。

如果想知道有哪些的話,可以下指令看一下。

kubectl get nodes --show-labels

上面是簡單的寫法,
詳細過程可以參考 矽谷牛大大的文章,連結在下方。

ref.